package com.h3c.ptability.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author chenyifan
 * @date 2022/5/20 15:07
 */
@Slf4j
public class WordUtil {

    private static Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);

    @SneakyThrows
    public static void replaceTemplateWrite(String templatePath, Map<String, String> params, File destPathFile) {
        InputStream is = new FileInputStream(templatePath);
        XWPFDocument doc = new XWPFDocument(is);
        //替换段落里面的变量
        replaceInPara(doc, params);
        //替换表格里面的变量
        replaceInTable(doc, params);
        BufferedOutputStream os = FileUtil.getOutputStream(destPathFile);
        doc.write(os);
        close(os);
        close(is);
    }

    /**
     * 替换段落里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    private static void replaceInPara(XWPFDocument doc, Map<String, String> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            replaceInPara(para, params);
        }
    }

    /**
     * 替换段落里面的变量
     *
     * @param para   要替换的段落
     * @param params 参数
     */
    private static void replaceInPara(XWPFParagraph para, Map<String, String> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        if (matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                String runText = run.toString();
                matcher = matcher(runText);
                if (matcher.find()) {
                    while ((matcher = matcher(runText)).find()) {
                        runText = matcher.replaceFirst(String.valueOf(StringUtils.isBlank(params.get(matcher.group(1))) ? "" : params.get(matcher.group(1))));
                    }
                    //直接调用XWPFRun的setText()方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
                    //所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。
                    int fontSize = run.getFontSize();
                    String fontFamily = run.getFontFamily();
                    boolean bold = run.isBold();
                    String color = run.getColor();
                    int value = run.getUnderline().getValue();
                    para.removeRun(i);
                    XWPFRun newRun = para.insertNewRun(i);
                    newRun.setFontSize(fontSize);
                    newRun.setFontFamily(fontFamily);
                    newRun.setBold(bold);
                    newRun.setColor(color);
                    newRun.setUnderline(UnderlinePatterns.valueOf(value));
                    newRun.setText(runText);
                }
            }
        }
    }

    /**
     * 替换表格里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    private static void replaceInTable(XWPFDocument doc, Map<String, String> params) {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceInPara(para, params);
                    }
                }
            }
        }
    }

    /**
     * 正则匹配字符串
     *
     * @param str
     * @return
     */
    private static Matcher matcher(String str) {
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     * 关闭输入流
     *
     * @param is
     */
    private static void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输出流
     *
     * @param os
     */
    private static void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//    /**
//     * 读取word模板并替换变量
//     *
//     * @param templatePath 模板路径
//     * @param params   要替换的内容
//     * @return word的Document
//     */
//    public static HWPFDocument replaceDoc(String templatePath, Map<String,String> params) {
//        try {
//            // 读取模板
//            FileInputStream tempFileInputStream = new FileInputStream(new File(templatePath));
//            HWPFDocument document = new HWPFDocument(tempFileInputStream);
//            // 读取文本内容
//            Range bodyRange = document.getRange();
//            // 替换内容
//            for (Map.Entry<String, String> entry : params.entrySet()) {
//                bodyRange.replaceText("${" + entry.getKey() + "}", entry.getValue());
//            }
//            return document;
//        } catch (Exception e) {
//            return null;
//        }
//
//    }

}
